#include "TcpClient.hpp"
#include <stdint.h>
#include "commom.h"
TcpClient::TcpClient(TcpSocketDataInfo *pTcpSocketDataInfo):do_recv(true),pTcpSocketDataInfo(pTcpSocketDataInfo) {
    createSocket();
    writeFD = fopen( "rawData.bin", "w" );
}

TcpClient::~TcpClient() {
    if (writeFD != NULL) {
        fclose(writeFD);
    }
}

void TcpClient::saveTofile(FILE *fd, unsigned char *buffer, int size) {
    static uint64_t index = 0;
    fwrite(buffer, sizeof(char), size, fd);
    /*
    for (int i = 0; i < size; i++, index++) {
        fprintf(fd, "[%5d] = %x\n", index, buffer[i]);
    }*/
}

void TcpClient::createSocket() {
    struct addrinfo hints, * res;
    int status;
    //clear hints
    memset(&hints, 0, sizeof hints);
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_flags = AI_PASSIVE;

    status = getaddrinfo(TCP_IP,TCP_PORT, &hints, &pAddrinfo);
    if(status != 0)
    {
        fprintf(stderr, "Error getaddrinfo\n");
        exit(1);
    }

    socket_id = socket(pAddrinfo->ai_family, pAddrinfo->ai_socktype, pAddrinfo->ai_protocol);
    if(socket_id < 0)
    {
        fprintf(stderr, "Error socket \n");
        exit(2);
    }

}
void printErrorPackage(char *pointer, int size, int pulsCount) {
	printf("===============================\n");
	printf("error size is %d\n", size);
	for (int i = 0; i < size; ++i)
	{
		printf("[%d] = %d\n", i, pointer[i]);
		/* code */
	}
	printf("pulsCount is %d\n", pulsCount);
	printf("===============================\n");
}

extern "C" void gSaveRawDataTofile(FILE *fd, unsigned char *buffer, int size) {
    static uint64_t index = 0;
    for (int i = 0; i < size; i++, index++) {
        fprintf(fd, "[%5d] = %x\n", index, buffer[i]);
    }
}

extern "C" void tcpSocketRecv ( void * pParam )
{
	TcpClient *client = reinterpret_cast < TcpClient * > ( pParam );
	unsigned char head[16] = {0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55};
	unsigned char end[16]  = {0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa};
	char *buffer;
	unsigned char headBuffer[20];
	int size = 1024;
	int count = 0;
	int headSize = 0;
	int midSize = 0;
	int endSize = 0;
	unsigned char *pointer;
	uint32_t eventCount = 0;
	int _tempRecvCount = 0;
	int pulsCount = 0;
#define Recv_Max_Length 10240
    FILE *writeFD = fopen( "rawData.bin", "w" );

    buffer = (char *)malloc(Recv_Max_Length);
	TcpSocketDataInfo *pTcpSocketDataInfo = client->pTcpSocketDataInfo;

	    int numbytes = 0;
//        pointer = buffer;
		while(client->do_recv) {
//				memset(buffer, 0x00, 1024);
				int mSize = recv(client->socket_id, buffer, Recv_Max_Length,0);
            
                epicsMutexLock(pTcpSocketDataInfo->mutex);
                uint64_t nUsed = epicsRingBytesUsedBytes(pTcpSocketDataInfo->ring);
				if (mSize > 0)
				{
                    client->saveTofile(client->writeFD, (unsigned char *)buffer, mSize);
                    
                    if (nUsed < uint64_t(ByteRingSize * 80 / 100)) {
                        epicsRingBytesPut(pTcpSocketDataInfo->ring, (char *)buffer, mSize);
                    }
				}
            epicsMutexUnlock(pTcpSocketDataInfo->mutex);
            epicsEventSignal(pTcpSocketDataInfo->consumerEvent);

	}
    fclose(writeFD);
    free(buffer);

}



void TcpClient::start() {
	int status;
	if(socket_id >= 0) {
		    status = connect(socket_id, pAddrinfo->ai_addr, pAddrinfo->ai_addrlen);
		    if(status < 0)
		    {
		        fprintf(stderr, "Error connect \n");
		        exit(3);
		    } else {
		    	printf("...............................................................tcp connect success................................................\n");
		    }
		}
	epicsThreadSleep(0.1);
	epicsThreadCreate (
        "client circuit", epicsThreadPriorityMedium,
        epicsThreadGetStackSize(epicsThreadStackMedium),
        tcpSocketRecv, this );
	epicsThreadSleep(0.1);
	DataRingConsumeThread *runnable = new DataRingConsumeThread(pTcpSocketDataInfo);
	pDataRingConsumeThread = new epicsThread(*runnable, "DataRingConsumeThread", epicsThreadGetStackSize(epicsThreadStackMedium));
	pDataRingConsumeThread->start();
}


void TcpClient::close() {


	}

int TcpClient::receive(unsigned char *buffer, int size) {
    return 0;
}

